home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Peter Lewis / PNL Libraries / MyFMenus.p < prev    next >
Encoding:
Text File  |  1994-08-27  |  7.6 KB  |  323 lines  |  [TEXT/PJMM]

  1. unit MyFMenus;
  2.  
  3. { From Peter's PNL Libraries }
  4. { Copyright 1992 Peter N Lewis }
  5. { This source may be used for any non-commercial purposes as long as I get a mention }
  6. { in the About box and Docs of any derivative program.  It may not be used in any commercial }
  7. { application without my permission }
  8.  
  9. interface
  10.  
  11.     var
  12.         thefmenu, thefitem: integer;
  13.         menu_modifiers: integer;
  14.  
  15.     procedure InitFMenus (default: procptr);
  16. { procedure default(themenu,theitem:integer) }
  17. { Call this once at the start of the application, before all the others }
  18.     procedure FinishFMenus;
  19. { Call this ones as the application quits }
  20.  
  21.     function GetFMenu (id: integer): MenuHandle;
  22. { Call this in place of GetMenu, to read in an fmnu resource.  Use InsertMenu to add it to the menu bar }
  23.     procedure SetFCommand (command: OSType; cmdproc: procptr);
  24. { procedure cmdproc }
  25. { Call this to associate a procedure with a command OSType }
  26.     procedure SetFSetMenu (command: OSType; smproc: procptr);
  27. { procedure smproc(themenu,theitem:integer) }
  28. { Call this to associate a procedure for enabling/disabling the menu item }
  29.     procedure SetFBoth (command: OSType; cmdproc, smproc: procptr);
  30. { This is just a short form to set both the command and SetMenu procedures }
  31.  
  32.     procedure SetFMenus;
  33. { Call this before MenuKey or MenuSelect to set the enables of all the menus }
  34.     procedure SetFMenu (themenu: integer);
  35. { Call this to set the enables of all the items in themenu }
  36.     procedure DoFMenu (themenu, theitem: integer);
  37. { Call this to act on a menu selection from either MenuSelect or MenuKey }
  38.  
  39. { You probably won't need these }
  40.     procedure AddFCommand (themenu, theitem: integer; command: OSType);
  41. { Call this to associate a menu item with an OSType - normally done by GetFMenu }
  42.     procedure GetCommand (themenu, theitem: integer; var command: OSType);
  43. { Call this to figure out what command OSType is associated with a menu item - normally done via DoFMenu }
  44.     procedure DoCommand (themenu, theitem: integer; command: OSType);
  45. { Call this to execute a menu command - normally done via DoFMenu }
  46.  
  47. implementation
  48.  
  49.     uses
  50.         BaseGlobals;
  51. { import the quitNow variable - this is only used for cosmetic reasons, so that }
  52. { the File menu stays highlighted until the application quits }
  53. { Don't forget that you need to turn on the "Uses" Extensions in the Compile Options }
  54.  
  55.     procedure DoSMP (themenu, theitem: integer; smp: procptr);
  56.     inline
  57.         $205F, $4E90;
  58.  
  59.     procedure DoDefCMDP (themenu, theitem: integer; cmdp: procptr);
  60.     inline
  61.         $205F, $4E90;
  62.  
  63.     procedure DoCMDP (cmdp: procptr);
  64.     inline
  65.         $205F, $4E90;
  66.  
  67.     type
  68.         fmenuHeader = record
  69.                 visible: integer;
  70.                 count: integer;
  71.                 unknown1: integer;
  72.                 menuID: integer;
  73.                 unknown2: integer;
  74.                 unknown3: integer;
  75.                 name: str63;
  76.             end;
  77.         fmenuHeaderPtr = ^fmenuHeader;
  78.         fmenuItem = packed record
  79.                 command: OSType;
  80.                 mark: char;
  81.                 unknown2: byte;
  82.                 cmdKey: char;
  83.                 disabled: byte;
  84.                 name: str63;
  85.             end;
  86.         fmenuItemPtr = ^fmenuItem;
  87.         convertRecord = record
  88.                 menu, item: integer;
  89.                 cmd: OSType;
  90.                 cmdp, smp: procptr;
  91.             end;
  92.         convertArray = array[1..1000] of convertRecord;
  93.         convertPtr = ^convertArray;
  94.         convertHandle = ^convertPtr;
  95.  
  96.     var
  97.         defaultproc: procptr;
  98.         convert_count: integer;
  99.         converts: convertHandle;
  100.  
  101. {$S Init}
  102.     procedure InitFMenus (default: procptr);
  103. { procedure default(themenu,theitem:integer) }
  104.     begin
  105.         defaultproc := default;
  106.         convert_count := 0;
  107.         converts := convertHandle(NewHandle(0));
  108.     end;
  109.  
  110. {$S Term}
  111.     procedure FinishFMenus;
  112.     begin
  113.         DisposHandle(handle(converts));
  114.     end;
  115.  
  116. {$S Init}
  117.     procedure AddFCommand (themenu, theitem: integer; command: OSType);
  118.     begin
  119.         if BAND(convert_count, 7) = 0 then
  120.             SetHandleSize(handle(converts), (convert_count + 8) * SizeOf(convertRecord));
  121.         convert_count := convert_count + 1;
  122.         with converts^^[convert_count] do begin
  123.             menu := themenu;
  124.             item := theitem;
  125.             cmd := command;
  126.             cmdp := defaultproc;
  127.             smp := nil;
  128.         end;
  129.     end;
  130.  
  131. {$S Init}
  132.     procedure NextPtr (var p: univ ptr; sp: univ ptr);
  133.     begin
  134.         p := ptr(longInt(sp) + sp^ + 2 - ord(odd(sp^)));
  135.     end;
  136.  
  137. {$S Init}
  138.     function GetFMenu (id: integer): MenuHandle;
  139.         var
  140.             h: handle;
  141.             mh: menuHandle;
  142.             ph: fmenuHeaderPtr;
  143.             p: fmenuItemPtr;
  144.             s: string[70];
  145.             i: integer;
  146.     begin
  147.         h := GetResource('fmnu', id);
  148.         HLock(h);
  149.         ph := fmenuHeaderPtr(h^);
  150.         mh := NewMenu(ph^.menuID, ph^.name);
  151.         NextPtr(p, @ph^.name);
  152.         for i := 1 to ph^.count do begin
  153.             if p^.name = '-' then
  154.                 AppendMenu(mh, '(-')
  155.             else begin
  156.                 AddFCommand(ph^.menuID, i, p^.command);
  157.                 s := p^.name;
  158.                 if p^.mark <> chr(0) then
  159.                     s := concat(s, '!', p^.mark);
  160.                 if p^.cmdKey <> chr(0) then
  161.                     s := concat(s, '/', p^.cmdKey);
  162.                 if p^.disabled = 1 then
  163.                     s := concat('(', s);
  164.                 AppendMenu(mh, s);
  165.             end;
  166.             NextPtr(p, @p^.name);
  167.         end;
  168.         ReleaseResource(h);
  169.         GetFMenu := mh;
  170.     end;
  171.  
  172. {$S}
  173.     procedure FindCommand (command: OSType; var cmdproc: procptr);
  174.         var
  175.             i: integer;
  176.     begin
  177.         i := 1;
  178.         while i <= convert_count do begin
  179.             with converts^^[i] do
  180.                 if cmd = command then begin
  181.                     cmdproc := cmdp;
  182.                     Exit(FindCommand);
  183.                 end;
  184.             i := i + 1;
  185.         end;
  186.         cmdproc := defaultproc;
  187.     end;
  188.  
  189. {$S}
  190.     procedure FindMenu (themenu, theitem: integer; var i: integer);
  191.     begin
  192.         i := 1;
  193.         while i <= convert_count do begin
  194.             with converts^^[i] do
  195.                 if (menu = themenu) and (item = theitem) then
  196.                     Exit(FindMenu);
  197.             i := i + 1;
  198.         end;
  199.         i := -1;
  200.     end;
  201.  
  202. {$S Init}
  203.     procedure SetFCommand (command: OSType; cmdproc: procptr);
  204. { procedure cmdproc }
  205.         var
  206.             i: integer;
  207.     begin
  208.         for i := 1 to convert_count do
  209.             with converts^^[i] do
  210.                 if cmd = command then
  211.                     cmdp := cmdproc;
  212.     end;
  213.  
  214. {$S Init}
  215.     procedure SetFSetMenu (command: OSType; smproc: procptr);
  216. { procedure smproc }
  217.         var
  218.             i: integer;
  219.     begin
  220.         for i := 1 to convert_count do
  221.             with converts^^[i] do
  222.                 if cmd = command then
  223.                     smp := smproc;
  224.     end;
  225.  
  226. {$S Init}
  227.     procedure SetFBoth (command: OSType; cmdproc, smproc: procptr);
  228. { procedure smproc }
  229.         var
  230.             i: integer;
  231.     begin
  232.         for i := 1 to convert_count do
  233.             with converts^^[i] do
  234.                 if cmd = command then begin
  235.                     cmdp := cmdproc;
  236.                     smp := smproc;
  237.                 end;
  238.     end;
  239.  
  240. {$S}
  241.     procedure GetCommand (themenu, theitem: integer; var command: OSType);
  242.         var
  243.             i: integer;
  244.     begin
  245.         FindMenu(themenu, theitem, i);
  246.         if i = -1 then
  247.             command := 'xxx0'
  248.         else
  249.             command := converts^^[i].cmd;
  250.     end;
  251.  
  252. {$S}
  253.     procedure DoCmd (themenu, theitem: integer; cmdp: procptr);
  254.     begin
  255.         thefmenu := themenu;
  256.         thefitem := theitem;
  257.         if cmdp = defaultproc then
  258.             DoDefCMDP(themenu, theitem, cmdp)
  259.         else
  260.             DoCMDP(cmdp);
  261.     end;
  262.  
  263. {$S}
  264.     procedure DoCommand (themenu, theitem: integer; command: OSType);
  265.         var
  266.             cmdproc: procptr;
  267.     begin
  268.         FindCommand(command, cmdproc);
  269.         DoCmd(themenu, theitem, cmdproc);
  270.     end;
  271.  
  272. {$S}
  273.     procedure DoFMenu (themenu, theitem: integer);
  274.         var
  275.             i: integer;
  276.     begin
  277.         FindMenu(themenu, theitem, i);
  278.         if i = -1 then
  279.             DoCmd(themenu, theitem, defaultproc)
  280.         else
  281.             with converts^^[i] do
  282.                 DoCmd(themenu, theitem, cmdp);
  283.         if not quitNow then
  284.             HiliteMenu(0);
  285.     end;
  286.  
  287. {$S}
  288.     procedure SetFMenus;
  289.         var
  290.             i: integer;
  291.             dummy: boolean;
  292.             er: EventRecord;
  293.     begin
  294.         dummy := OSEventAvail(everyEvent, er);
  295.         menu_modifiers := er.modifiers;
  296.         for i := 1 to convert_count do begin
  297.             with converts^^[i] do begin
  298.                 if smp <> nil then begin
  299.                     DoSMP(menu, item, smp);
  300.                 end;
  301.             end;
  302.         end;
  303.     end;
  304.  
  305. {$S}
  306.     procedure SetFMenu (themenu: integer);
  307.         var
  308.             i: integer;
  309.             dummy: boolean;
  310.             er: EventRecord;
  311.     begin
  312.         dummy := OSEventAvail(everyEvent, er);
  313.         menu_modifiers := er.modifiers;
  314.         for i := 1 to convert_count do begin
  315.             with converts^^[i] do begin
  316.                 if (themenu = menu) & (smp <> nil) then begin
  317.                     DoSMP(menu, item, smp);
  318.                 end;
  319.             end;
  320.         end;
  321.     end;
  322.  
  323. end.